const { BaseCommand } = require("./base");
const path = require("node:path");
const {
    get_file_list,
    get_fst_file,
    get_full_path,
    processRename,
} = require("../utils/file_tool");
const fs = require("node:fs");
const { progress } = require("../utils/display_tool");
const { Alignment, alignStr } = require("../utils/transform_tool");
const { clearLine } = require("../utils/interaction_tool");
const { info } = require("../utils/log_tool");

class ZipCommand extends BaseCommand {
    async execute() {
        const AdmZip = require("adm-zip");
        const data = this.selfData;
        const files = get_file_list(data.src, undefined, true);
        let base = data.base;
        if (base) {
            base = get_fst_file(base);
        }
        // creating archives
        var zip = new AdmZip();

        // add file directly
        // var content = "inner content of the file";
        // zip.addFile("test.txt", Buffer.alloc(content.length, content), "entry comment goes here");
        // get everything as a buffer
        // var willSendthis = zip.toBuffer();
        // add local file
        for (let index = 0; index < files.length; index++) {
            const file = files[index];
            let zipPath = base ? path.relative(base, path.dirname(file)) : "";
            if (data.base_range) {
                const zipPathParts = zipPath
                    .split("\\")
                    .slice(...data.base_range);
                zipPath = path.join(...zipPathParts);
            }
            let entryName = path.join(zipPath, path.basename(file));
            entryName = processRename(entryName, data.options?.rename);
            const show_src = entryName;
            data.verbose &&
                progress(index, files.length, {
                    desc: `Add ${show_src}`,
                    depth: 0,
                    align: true,
                });
            // zip.addLocalFile(file, zipPath);
            zip.addFile(entryName, fs.readFileSync(file));
        }
        clearLine();
        data.verbose &&
            progress(files.length, files.length, {
                desc: `压缩中...`,
                depth: 0,
                align: true,
            });
        // or write everything to disk
        if (data.dst) {
            const dst = get_full_path(data.dst);
            await new Promise((resolve) => {
                zip.writeZip(dst, (err) => {
                    if (err) {
                        throw err;
                    }
                    resolve();
                });
            });
        } else {
            const buffer = zip.toBuffer();
            return buffer;
        }
        data.verbose &&
            progress(files.length, files.length, {
                desc: `压缩完成!`,
                depth: 0,
                color: "green",
            });
        data.verbose && info("");
    }
}

module.exports = {
    ZipCommand,
};
